package com.qubuyer.core.http

import android.util.Log
import com.google.gson.JsonParser
import com.qubuyer.core.ext.application
import com.qubuyer.core.ext.toJson
import okhttp3.OkHttpClient
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.logging.HttpLoggingInterceptor
import okio.Buffer
import java.io.UnsupportedEncodingException
import java.nio.charset.Charset
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.*
import java.util.concurrent.TimeUnit

/**
 * Author: linwg
 * Time: 2020/10/15 0015
 * Description:
 */
class OkHttpUtil private constructor() {
    var okHttpClient: OkHttpClient

    companion object {
        val util: OkHttpUtil by lazy { OkHttpUtil() }
        val token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6NDM4LCJ0aW1lIjoxNjEyMzM2MDA5fQ.XQARNxOMnduMwY5I_Ld7jw2j8jlhxBnSrBCStnB8cEs"
    }

    init {
        val builder = OkHttpClient.Builder()
        val interceptors = application.interceptors()
        interceptors.forEach {
            builder.addInterceptor(it)
        }
        val networkInterceptors = application.networkInterceptors()
        networkInterceptors.forEach {
            builder.addNetworkInterceptor(it)
        }
//        builder.addInterceptor {
//            val request = it.request()
//            val needAuth = request.header("NeedAuth") == null
//            val method = request.method
//            var charset = Charset.forName("UTF-8")
//            if (method.toLowerCase() == "post") {
//                val contentType = request.body?.contentType()
//                charset = contentType?.charset(charset)
//                if (contentType?.type?.toLowerCase() == "multipart") {
//                    if (needAuth) {
//                        it.proceed(request.newBuilder().addHeader("token", token).build())
//                    } else {
//                        it.proceed(request)
//                    }
//                } else {
//                    val buffer = Buffer()
//                    request.body?.writeTo(buffer)
//                    val bodyString = if(request.body == null)  "" else buffer.readString(charset)
//                    when (request.body?.contentType()?.subtype) {
//                        "json" -> {
//                            val je = JsonParser.parseString(bodyString)
//                            val keySet = je.asJsonObject.keySet()
//                            val treeMap = TreeMap<String, String>()
//                            keySet.forEach { key ->
//                                treeMap[key] = je.asJsonObject[key].asString
//                            }
//                            treeMap["sign"] = getSign(treeMap)
//                            val newRequestBody = treeMap.toJson().toRequestBody(request.body?.contentType())
//                            val newRequest = request.newBuilder().apply { if(needAuth){ addHeader("token",token) } }.post(newRequestBody).build()
//                            it.proceed(newRequest)
//                        }
//                        "x-www-form-urlencoded" -> {
//                            val split = bodyString.split("&")
//                            val treeMap = TreeMap<String, String>()
//                            split.forEach { params ->
//                                val kv = params.split("=")
//                                treeMap[kv[0]] = kv[1]
//                            }
//                            treeMap["sign"] = getSign(treeMap)
//                            val append = if (bodyString.isNotEmpty()) "&" else ""
//                            val newRequestBody = "$bodyString${append}timestamp=${treeMap["timestamp"]}&sign=${treeMap["sign"]}".toRequestBody(request.body?.contentType())
//                            val newRequest = request.newBuilder().apply { if(needAuth){ addHeader("token",token) } }.post(newRequestBody).build()
//                            it.proceed(newRequest)
//                        }
//                        else -> {
//                            if (needAuth) {
//                                it.proceed(request.newBuilder().addHeader("token", token).build())
//                            } else {
//                                it.proceed(request)
//                            }
//                        }
//                    }
//                }
//            } else if (method.toLowerCase() == "get") {
//                val queryParameterNames = request.url.queryParameterNames
//                val treeMap = TreeMap<String, String>()
//                queryParameterNames.forEachIndexed { index, name ->
//                    treeMap[name] = request.url.queryParameterValue(index) ?: ""
//                }
//                treeMap["sign"] = getSign(treeMap)
//                val newUrl = request.url.newBuilder().addQueryParameter("timestamp", treeMap["timestamp"]).addQueryParameter("sign", treeMap["sign"]).build()
//                val newRequest = request.newBuilder().apply { if(needAuth){ addHeader("token",token) } }.get().url(newUrl).build()
//                it.proceed(newRequest)
//            } else {
//                if (needAuth) {
//                    it.proceed(request.newBuilder().addHeader("token", token).build())
//                } else {
//                    it.proceed(request)
//                }
//            }
//        }
        builder.addInterceptor(HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
            val declaredField = this::class.java.getDeclaredField("logger")
            declaredField.isAccessible = true
            declaredField.set(this, object : HttpLoggingInterceptor.Logger {
                override fun log(message: String) {
                    Log.e("HttpUtil", message)
                }
            })
        })
        okHttpClient = builder
                .connectTimeout(60000L, TimeUnit.MILLISECONDS)
                .readTimeout(60000L, TimeUnit.MILLISECONDS)
                .build()
    }

//    private val salt = "qumaimai20201215"
//
//    private fun getSign(map: TreeMap<String, String>): String {
//        map["timestamp"] = System.currentTimeMillis().toString().substring(0, 10)
//        val entries: Set<Map.Entry<String, String>> = map.entries
//        val iterator = entries.iterator()
//        val stringBuilder = StringBuilder()
//        while (iterator.hasNext()) {
//            val entry = iterator.next()
//            stringBuilder.append(entry.key)
//            stringBuilder.append("=")
//            stringBuilder.append(entry.value)
//            stringBuilder.append("&")
//        }
//        var s = stringBuilder.toString()
//        if (s.isNotEmpty()) {
//            s = s.substring(0, s.length - 1)
//        }
//        s += salt
//        return MD5(s).toUpperCase()
//    }
//
//    private fun MD5(`in`: String): String {
//        val hash: ByteArray
//        hash = try {
//            MessageDigest.getInstance("MD5").digest(`in`.toByteArray(charset("UTF-8")))
//        } catch (e: NoSuchAlgorithmException) {
//            throw RuntimeException("Huh, MD5 should be supported?", e)
//        } catch (e: UnsupportedEncodingException) {
//            throw RuntimeException("Huh, UTF-8 should be supported?", e)
//        }
//        val hex = java.lang.StringBuilder(hash.size * 2)
//        for (b in hash) {
//            if (b.toInt() and 0xFF < 0x10) hex.append("0")
//            hex.append(Integer.toHexString(b.toInt() and 0xFF))
//        }
//        return hex.toString()
//    }
}